#include "gameClient.h"

GameClient* game;
bool keys[256];

void GameClient::createPlayer(int index)
{
	Ogre::Entity* NinjaEntity = mSceneMgr->createEntity("ninja.mesh");
	Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    node->attachObject(NinjaEntity);
    clientData *client = game->GetClientPointer(index);
	client->myNode = node;
	client->command.catchup = false;
    client->command.stop    = false;

	Ogre::Entity* NinjaEntityb = mSceneMgr->createEntity("ninja.mesh");
    Ogre::SceneNode* nodeb = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    nodeb->attachObject(NinjaEntityb);
   // clientData *client = game->GetClientPointer(index);
    myServerNode = nodeb;
    LogString("createServerPlayer index:%d",index);
}
//-------------------------------------------------------------------------------------
void GameClient::createScene(void)
{
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.75, 0.75, 0.75));

    Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");
    pointLight->setType(Ogre::Light::LT_POINT);
    pointLight->setPosition(Ogre::Vector3(250, 150, 250));
    pointLight->setDiffuseColour(Ogre::ColourValue::White);
    pointLight->setSpecularColour(Ogre::ColourValue::White);
}
//-------------------------------------------------------------------------------------
bool GameClient::processUnbufferedInput(const Ogre::FrameEvent& evt)
{
    if (mKeyboard->isKeyDown(OIS::KC_I)) // Forward
    {
		keys[VK_UP] = TRUE;
    }
	else
	{
        keys[VK_UP] = FALSE;
	}
    if (mKeyboard->isKeyDown(OIS::KC_K)) // Backward
    {
		keys[VK_DOWN] = TRUE;
    }
	else
	{
        keys[VK_DOWN] = FALSE;
	}
    if (mKeyboard->isKeyDown(OIS::KC_J)) // Left - yaw or strafe
    {
		keys[VK_LEFT] = TRUE;
    }
	else
	{
        keys[VK_LEFT] = FALSE;
	}
    if (mKeyboard->isKeyDown(OIS::KC_L)) // Right - yaw or strafe
    {
		keys[VK_RIGHT] = TRUE;
    }
	else
	{
        keys[VK_RIGHT] = FALSE;
	}

    return true;
}
//-------------------------------------------------------------------------------------
bool GameClient::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
    bool ret = BaseApplication::frameRenderingQueued(evt);

    if(!processUnbufferedInput(evt)) return false;

	if(game != NULL)
	{
		game->CheckKeys();
		game->RunNetwork(evt.timeSinceLastFrame * 1000);
		rendertime = evt.timeSinceLastFrame;
	}
    return ret;
}

GameClient::GameClient(const char* serverIP)
{
	mServerIP = serverIP;
 	networkClient	= new dreamClient;
 	clientList		= NULL;
 	localClient		= NULL;
 	memset(&inputClient, 0, sizeof(clientData));
 	frametime		= 0.0f;
 	rendertime		= 0.0f;
 	init			= false;
	serverX         = 0.0f;
	serverY         = 0.0f;
 }

 GameClient::~GameClient()
 {
 	delete networkClient;
 }

 void GameClient::Shutdown(void)
 {
 	Disconnect();
 }

 clientData *GameClient::GetClientPointer(int index)
 {
 	for(clientData *clList = clientList; clList != NULL; clList = clList->next)
 	{
 		if(clList->index == index)
 			return clList;
 	}
 	return NULL;
 }

void GameClient::CheckKeys(void)
{
	inputClient.command.key = 0;
 	if(keys[VK_ESCAPE])
 	{
 		Shutdown();
 		keys[VK_ESCAPE] = false;
 	}
 	if(keys[VK_DOWN])
 	{
 		inputClient.command.key |= KEY_DOWN;
 	}
 	if(keys[VK_UP])
 	{
 		inputClient.command.key |= KEY_UP;
 	}
 	if(keys[VK_LEFT])
 	{
 		inputClient.command.key |= KEY_LEFT;
 	}
 	if(keys[VK_RIGHT])
 	{
 		inputClient.command.key |= KEY_RIGHT;
 	}
 	inputClient.command.msec = (int) (frametime * 1000);
 }

 void GameClient::CalculateVelocity(command_t *command, float frametime)
 {
 	float multiplier = 100.0f;

 	command->vel.x = 0.0f;
 	command->vel.y = 0.0f;

 	if(command->key & KEY_UP)
	{

		//command->vel.y += multiplier * frametime;
		command->vel.y += 1;
	}

	if(command->key & KEY_DOWN)
	{
		//command->vel.y += -multiplier * frametime;
        command->vel.y += -1;
	}

	if(command->key & KEY_LEFT)
	{
		//command->vel.x += -multiplier * frametime;
		command->vel.x += -1;
	}

	if(command->key & KEY_RIGHT)
	{
		//command->vel.x += multiplier * frametime;
		command->vel.x += 1;
	}


	float length = sqrt(pow(command->vel.x, 2) + pow(command->vel.y, 2));
	if(length != 0.0)
	{
	   command->vel.x = command->vel.x/length * 0.1 * frametime * 1000;
	   command->vel.y = command->vel.y/length * 0.1 * frametime * 1000;
	}
    LogString("command->vel.x %f", command->vel.x);
	LogString("command->vel.y %f", command->vel.y);

	//LogString("interp velX %f", command->vel.x);
	//LogString("interp velY %f", command->vel.y);
    //LogString("frametime %f", frametime);
		
 }

void GameClient::MoveRemotePlayers(void)
{
 	if(!localClient)
		return;

	clientData *client = clientList;
 
 	Ogre::Vector3 transVector = Ogre::Vector3::ZERO;

 	for( ; client != NULL; client = client->next)
 	{
		CalculateVelocity(&client->command, rendertime);

 		client->command.origin.x += client->command.vel.x;
 		client->command.origin.y += client->command.vel.y;

        //transVector.x = client->command.origin.x;
        //transVector.y = client->command.origin.y;

		transVector.x = client->command.vel.x;
		transVector.y = client->command.vel.y;
			
		//client->myNode->setPosition(transVector * rendertime);
	    client->myNode->translate  (transVector, Ogre::Node::TS_WORLD);
	}
 }

void GameClient::MoveServerPlayer(void)
{
    Ogre::Vector3 transVector = Ogre::Vector3::ZERO;

    transVector.x = serverX;
    transVector.y = serverY;
	
	//if (mServerPlayerToggle)
	if(myServerNode)
	   myServerNode->setPosition(transVector);
}


void GameClient::ProcessTick(clientData *client)
{

/*
     Ogre::Vector3 toDest   = Ogre::Vector3::ZERO;

     float deltaX = client->serverFrame.origin.x - client->myNode->getPosition().x;
     float deltaY = client->serverFrame.origin.y - client->myNode->getPosition().y;

	 float dist = pow(deltaX, 2) + pow(deltaY, 2);


   //float totalVel = sqrt(pow(velX, 2) + pow(velY, 2));

       toDest.x = client->serverFrame.origin.x;
	   toDest.y = client->serverFrame.origin.y;

       toDest = toDest - client->myNode->getPosition();
	   toDest.normalise();

	   //toDest = toDest * totalVel;
       toDest = toDest * 0.1;

	   if((toDest.x > 0.0 && client->serverFrame.vel.x < 0.0) || (toDest.x < 0.0 && client->serverFrame.vel.x > 0.0) ||
		(toDest.y > 0.0 && client->serverFrame.vel.y < 0.0) || (toDest.y < 0.0 && client->serverFrame.vel.y > 0.0))
	   {
          client->command.vel.x = client->command.vel.x;
	      client->command.vel.y = client->command.vel.y;
          LogString("1");
	   }
	   else
	   {
          client->command.vel.x = toDest.x;
	      client->command.vel.y = toDest.y;
	   }
*/

	float deltaX = client->serverFrame.origin.x - client->myNode->getPosition().x;
    float deltaY = client->serverFrame.origin.y - client->myNode->getPosition().y;

	float dist = pow(deltaX, 2) + pow(deltaY, 2);

	  if(dist > 400.0)
	   {
          client->command.catchup = true; 
	   }

	   if(dist < 1.0)
          client->command.catchup = false;

	   if(client->serverFrame.vel.x == 0.0 && client->serverFrame.vel.y == 0.0)
	   {
		  client->command.stop = true;
		  //client->command.vel.x = 0.0;
	      //client->command.vel.y = 0.0;
	   }
	   else
          client->command.stop = false;


	   
	     
	   if(client->command.catchup == true && client->command.stop == false)
	   {
		   Ogre::Vector3 serverDest  = Ogre::Vector3::ZERO;
		   Ogre::Vector3 myDest      = Ogre::Vector3::ZERO;
		   
			//toDest.x = client->serverFrame.origin.x;
			//toDest.y = client->serverFrame.origin.y;

		   // toDest = toDest - client->myNode->getPosition();

			serverDest.x = client->serverFrame.vel.x;
			serverDest.y = client->serverFrame.vel.y;
			serverDest.normalise();
			float multiplier = sqrt(dist)/20.0 * 500.0;
			serverDest = serverDest * multiplier;
			serverDest.x = client->serverFrame.origin.x + serverDest.x;
			serverDest.y = client->serverFrame.origin.y + serverDest.y;

			myDest = serverDest - client->myNode->getPosition();

			float predictDist = pow(myDest.x, 2) + pow(myDest.y, 2);
			predictDist = sqrt(predictDist);

			myDest.normalise();

			float time = sqrt(dist) * 250.0;

			//if(predictDist > 500)
              // myDest = myDest * 0.1;
			//else
				//myDest = myDest * 0.1;

			//myDest = myDest * 0.1;
			myDest = myDest * predictDist/time;

			client->command.vel.x = myDest.x;
	        client->command.vel.y = myDest.y;

			LogString("catchup velX %f", client->command.vel.x);
	        LogString("catchup velY %f", client->command.vel.y);

	   }
	  
		  

		  //transVector.x = client->command.vel.x;
	      //transVector.y = client->command.vel.y;

	     // LogString("interp velX %f", client->command.vel.x);
	      //LogString("interp velY %f", client->command.vel.y);
		
          //client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
	      //client->myNode->translate(transVector, Ogre::Node::TS_WORLD);
	  

	   //LogString("dist %f", dist);
	  //LogString("client->command.vel.x %f", client->command.vel.x);
	 // LogString("client->command.vel.y %f", client->command.vel.y);
}

void GameClient::interpolateTick(clientData *client)
{
   Ogre::Vector3 transVector = Ogre::Vector3::ZERO;

   if(client->command.catchup == true && client->command.stop == false)
   {
	  transVector.x = client->command.vel.x;
      transVector.y = client->command.vel.y;
      client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
   }
   else
   {
	  CalculateVelocity(&client->command, rendertime);
	  transVector.x = client->command.vel.x;
      transVector.y = client->command.vel.y;
      client->myNode->translate(transVector, Ogre::Node::TS_WORLD);
   }

/*
   Ogre::Vector3 transVector = Ogre::Vector3::ZERO;
   Ogre::Vector3 serverDest  = Ogre::Vector3::ZERO;
   Ogre::Vector3 myDest      = Ogre::Vector3::ZERO;
   
    //toDest.x = client->serverFrame.origin.x;
	//toDest.y = client->serverFrame.origin.y;

   // toDest = toDest - client->myNode->getPosition();

    serverDest.x = client->serverFrame.vel.x;
	serverDest.y = client->serverFrame.vel.y;
	serverDest.normalise();
	serverDest = serverDest * 500.0;
    serverDest.x = client->serverFrame.origin.x + serverDest.x;
	serverDest.y = client->serverFrame.origin.y + serverDest.y;

    myDest = serverDest - client->myNode->getPosition();

    float predictDist = pow(myDest.x, 2) + pow(myDest.y, 2);
    predictDist = sqrt(predictDist);

	myDest.normalise();
    //myDest = myDest * 0.1;
	myDest = myDest * predictDist/5000.0;

	Ogre::Vector3 toDest   = Ogre::Vector3::ZERO;

    float deltaX = client->serverFrame.origin.x - client->myNode->getPosition().x;
    float deltaY = client->serverFrame.origin.y - client->myNode->getPosition().y;

	float dist = pow(deltaX, 2) + pow(deltaY, 2);

	//toDest = toDest * totalVel;
    //toDest = toDest * 0.1;


   if(client->command.stop == true)
	{
		if(abs(deltaX) < 0.5 && abs(deltaY) < 0.5)
        {
           client->command.vel.x = 0.0;
		   client->command.vel.y = 0.0;
        }
		//else
	       //client->command.vel.x = deltaX/100;
	       //client->command.vel.y = deltaY/100;
	}
*/
/*
   if(client->serverFrame.vel.x == 0.0 && client->serverFrame.vel.y == 0.0)
   {
      if(abs(deltaX) < (0.1 * rendertime * 1000) && abs(deltaY) < (0.1 * rendertime * 1000))
        {
           client->command.vel.x = 0.0;
		   client->command.vel.y = 0.0;
		   LogString("threshold %f", 0.1 * rendertime * 1000);
        }

	  transVector.x = client->command.vel.x;
	  transVector.y = client->command.vel.y;
	  client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
   }
*/

   
/*
   if(client->command.stop == true)
   {

	  LogString("stop %f", 0.1 * rendertime * 1000);
      client->command.vel.x = toDest.x * 0.2;
	  client->command.vel.y = toDest.y * 0.2;

      if(abs(deltaX) < (0.1 * rendertime * 1000) && abs(deltaY) < (0.1 * rendertime * 1000))
        {
           client->command.vel.x = 0.0;
		   client->command.vel.y = 0.0;
		   LogString("threshold %f", 0.1 * rendertime * 1000);
        }

	  transVector.x = client->command.vel.x;
	  transVector.y = client->command.vel.y;
	  client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
   }
*/
/*
   //if(client->command.catchup == true && client->command.stop == false)
   if(client->command.stop == false)
   {
      client->command.vel.x = myDest.x;
	  client->command.vel.y = myDest.y;
      transVector.x = client->command.vel.x;
	  transVector.y = client->command.vel.y;
	  //LogString("interp velX %f", client->command.vel.x);
	  //LogString("interp velY %f", client->command.vel.y);
	  client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
   }
   else
   {
	CalculateVelocity(&client->command, rendertime);

	
   }
*/

    //transVector.x = client->command.vel.x;
	//transVector.y = client->command.vel.y;

	//LogString("interp velX %f", client->command.vel.x);
	//LogString("interp velY %f", client->command.vel.y);
		
    //client->myNode->translate(transVector * rendertime * 1000, Ogre::Node::TS_WORLD);
	//client->myNode->translate(transVector, Ogre::Node::TS_WORLD);

}
 
void GameClient::StartConnection()
{
	int ret = networkClient->Initialise("", mServerIP, 30004);

	if(ret == DREAMSOCK_CLIENT_ERROR)
	{
		char text[64];
		sprintf(text, "Could not open client socket");
	}
	Connect();
}

void GameClient::ReadPackets(void)
{
	char data[1400];
	struct sockaddr address;

	clientData *clList;

	int type;
	int ind;
	int local;
	int ret;
	int newTime;
	int time;

	char name[50];

	dreamMessage mes;
	mes.Init(data, sizeof(data));

	while(ret = networkClient->GetPacket(mes.data, &address))
	{
		mes.SetSize(ret);
		mes.BeginReading();

		type = mes.ReadByte();

		switch(type)
		{
		case DREAMSOCK_MES_ADDCLIENT:
			local	= mes.ReadByte();
			ind		= mes.ReadByte();
			strcpy(name, mes.ReadString());

			AddClient(local, ind, name);
			break;

		case DREAMSOCK_MES_REMOVECLIENT:
			ind = mes.ReadByte();

			LogString("Got removeclient %d message", ind);

			RemoveClient(ind);

			break;

		case USER_MES_FRAME:
			// Skip sequences
			mes.ReadShort();
			mes.ReadShort();

			newTime = dreamSock_GetCurrentSystemTime();
			//LogString("newTime %d", newTime);
            //LogString("oldTime %d", oldTime);
			time = newTime - oldTime;
            oldTime = newTime;
			//LogString("time %d", time);

			for(clList = clientList; clList != NULL; clList = clList->next)
			{
//				LogString("Reading DELTAFRAME for client %d", clList->index);
				ReadDeltaMoveCommand(&mes, clList);
				ProcessTick(clList);
				MoveServerPlayer();
			}

			break;

		case USER_MES_NONDELTAFRAME:
			// Skip sequences
			mes.ReadShort();
			mes.ReadShort();

			oldTime = dreamSock_GetCurrentSystemTime();

			clList = clientList;

			for(clList = clientList; clList != NULL; clList = clList->next)
			{
				LogString("Reading NONDELTAFRAME for client %d", clList->index);
				ReadMoveCommand(&mes, clList);
			}

			break;

		case USER_MES_SERVEREXIT:
			//MessageBox(NULL, "Server disconnected", "Info", MB_OK);
			Disconnect();
			break;

		}
	}
}

void GameClient::AddClient(int local, int ind, char *name)
{
	// First get a pointer to the beginning of client list
	clientData *list = clientList;
	clientData *prev;

	LogString("App: Client: Adding client with index %d", ind);

	// No clients yet, adding the first one
	if(clientList == NULL)
	{
		LogString("App: Client: Adding first client");

		clientList = (clientData *) calloc(1, sizeof(clientData));

		if(local)
		{
			LogString("App: Client: This one is local");
			localClient = clientList;
		}

		clientList->index = ind;
		strcpy(clientList->nickname, name);

		createPlayer(ind);
		clientList->next = NULL;
	}
	else
	{
		LogString("App: Client: Adding another client");

		prev = list;
		list = clientList->next;

		while(list != NULL)
		{
			prev = list;
			list = list->next;
		}

		list = (clientData *) calloc(1, sizeof(clientData));

		if(local)
		{
			LogString("App: Client: This one is local");
			localClient = list;
		}

		list->index = ind;
		strcpy(list->nickname, name);

		clientList->next = NULL;

		list->next = NULL;
		prev->next = list;

		createPlayer(ind);
	}

	// If we just joined the game, request a non-delta compressed frame
	if(local)
		SendRequestNonDeltaFrame();
}

void GameClient::RemoveClient(int ind)
{
	clientData *list = clientList;
	clientData *prev = NULL;
	clientData *next = NULL;

	// Look for correct client and update list
	for( ; list != NULL; list = list->next)
	{
		if(list->index == ind)
		{
			if(prev != NULL)
			{
				prev->next = list->next;
			}

			break;
		}

		prev = list;
	}

	// First entry
	if(list == clientList)
	{
		if(list)
		{
			next = list->next;
			free(list);
		}

		list = NULL;
		clientList = next;
	}

	// Other
	else
	{
		if(list)
		{
			next = list->next;
			free(list);
		}
		list = next;
	}
}

void GameClient::RemoveClients(void)
{
	clientData *list = clientList;
	clientData *next;

	while(list != NULL)
	{
		if(list)
		{
			next = list->next;
			free(list);
		}
		list = next;
	}
	clientList = NULL;
}

void GameClient::SendCommand(void)
{
	if(networkClient->GetConnectionState() != DREAMSOCK_CONNECTED)
		return;

	dreamMessage message;
	char data[1400];

	int i = networkClient->GetOutgoingSequence() & (COMMAND_HISTORY_SIZE-1);

	message.Init(data, sizeof(data));
	message.WriteByte(USER_MES_FRAME);						// type
	message.AddSequences(networkClient);					// sequences

	// Build delta-compressed move command
	BuildDeltaMoveCommand(&message, &inputClient);

	// Send the packet
	networkClient->SendPacket(&message);

	// Store the command to the input client's history
	memcpy(&inputClient.frame[i], &inputClient.command, sizeof(command_t));

	clientData *clList = clientList;

	// Store the commands to the clients' history
	for( ; clList != NULL; clList = clList->next)
	{
		memcpy(&clList->frame[i], &clList->command, sizeof(command_t));
	}
}

void GameClient::SendRequestNonDeltaFrame(void)
{
	char data[1400];
	dreamMessage message;
	message.Init(data, sizeof(data));

	message.WriteByte(USER_MES_NONDELTAFRAME);
	message.AddSequences(networkClient);

	networkClient->SendPacket(&message);
}

void GameClient::Connect(void)
{
	if(init)
	{
		LogString("ArmyWar already initialised");
		return;
	}

	LogString("GameClient::Connect");

	init = true;

	networkClient->SendConnect("myname");
}

void GameClient::Disconnect(void)
{
	if(!init)
		return;

	LogString("GameClient::Disconnect");

	init = false;
	localClient = NULL;
	memset(&inputClient, 0, sizeof(clientData));

	networkClient->SendDisconnect();
}

void GameClient::ReadMoveCommand(dreamMessage *mes, clientData *client)
{
	// Key
	client->serverFrame.key				= mes->ReadByte();

	// Origin
	client->serverFrame.origin.x		= mes->ReadFloat();
	client->serverFrame.origin.y		= mes->ReadFloat();
	client->serverFrame.vel.x			= mes->ReadFloat();
	client->serverFrame.vel.y			= mes->ReadFloat();

	// Read time to run command
	client->serverFrame.msec = mes->ReadByte();

	memcpy(&client->command, &client->serverFrame, sizeof(command_t));

	// Fill the history array with the position we got
	for(int f = 0; f < COMMAND_HISTORY_SIZE; f++)
	{
		client->frame[f].predictedOrigin.x = client->command.origin.x;
		client->frame[f].predictedOrigin.y = client->command.origin.y;
	}
}

void GameClient::ReadDeltaMoveCommand(dreamMessage *mes, clientData *client)
{
	int processedFrame;
	int flags = 0;

	// Flags
	flags = mes->ReadByte();

	// Key
	if(flags & CMD_KEY)
	{
		client->serverFrame.key = mes->ReadByte();

		client->command.key = client->serverFrame.key;
		LogString("Client %d: Read key %d", client->index, client->command.key);
	}

	if(flags & CMD_ORIGIN)
	{
		processedFrame = mes->ReadByte();
	}

	// Origin
	if(flags & CMD_ORIGIN)
	{

	}

	// Read time to run command
	client->serverFrame.origin.x = mes->ReadFloat();
	client->serverFrame.origin.y = mes->ReadFloat();

	client->serverFrame.vel.x = mes->ReadFloat();
	client->serverFrame.vel.y = mes->ReadFloat();

	serverX = client->serverFrame.origin.x;
	serverY = client->serverFrame.origin.y;

	//client->command.vel.x = client->serverFrame.vel.x;
	//client->command.vel.y = client->serverFrame.vel.y;

	client->command.msec = mes->ReadByte();
}

//-----------------------------------------------------------------------------
// Name: empty()
// Desc:
//-----------------------------------------------------------------------------
void GameClient::BuildDeltaMoveCommand(dreamMessage *mes, clientData *theClient)
{
	int flags = 0;
	int last = (networkClient->GetOutgoingSequence() - 1) & (COMMAND_HISTORY_SIZE-1);

	// Check what needs to be updated
	if(theClient->frame[last].key != theClient->command.key)
		flags |= CMD_KEY;

	// Add to the message
	// Flags
	mes->WriteByte(flags);

	// Key
	if(flags & CMD_KEY)
	{
		mes->WriteByte(theClient->command.key);
	}

	mes->WriteByte(theClient->command.msec);
}

//-----------------------------------------------------------------------------
// Name: empty()
// Desc:
//-----------------------------------------------------------------------------
void GameClient::RunNetwork(int msec)
{
	static int time = 0;
	time += msec;

	ReadPackets();

	
	for(clientData *clList = clientList; clList != NULL; clList = clList->next)
	{
	   interpolateTick(clList);
	}

	// Framerate is too high
	if(time > (1000 / 60)) {
		
		SendCommand();
		frametime = time / 1000.0f;
	    time = 0;
	}

	
	// Read packets from server, and send new commands
	
	
}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
    int main(int argc, char *argv[])
#endif
    {

        //ClientSideBaseGame* mClientSideBaseGame;
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        game = new GameClient(strCmdLine);
#else
        game = new GameClient(argv[1]);
#endif

		//game = new GameClient;
	    game->StartConnection();

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		StartLogConsole();
#endif

        try {
            game->go();
        } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " <<
                e.getFullDescription().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif